/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "libzlang_stdtypes.h"

struct ZlangDirectProperty_iterator
{
	struct ZlangObject	*collect_obj ;
	union
	{
		struct
		{
			int32_t			element_no ;
		} array_data ;
		struct
		{
			struct ZlangObject	*list_node ;
		} list_data ;
		struct
		{
			struct ZlangObject	*prev_key ;
			struct ZlangObject	*key ;
			struct ZlangObject	*next_key ;
		} map_data ;
	} data ;
	signed char				is_removed ;
} ;

ZlangDirectFunction_iterator_TravelFirst iterator_TravelFirst;
int iterator_TravelFirst( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *collect_obj )
{
	struct ZlangDirectProperty_iterator	*iterator_direct_prop = GetObjectDirectProperty(obj) ;
	int32_t					length ;
	int					nret = 0 ;
	
	if( ! IsTypeOf( rt , collect_obj , GetArrayObjectInRuntimeObjectsHeap(rt) ) && ! IsTypeOf( rt , collect_obj , GetListObjectInRuntimeObjectsHeap(rt) ) && ! IsTypeOf( rt , collect_obj , GetMapObjectInRuntimeObjectsHeap(rt) ) )
		return ZLANG_ERROR_TYPE_OF_OBJECT_NOT_MATCHED;
	
	IF_ATOMIC_OBJECT_THEN_LOCK_ANOTHER_OBJECT( obj , collect_obj )
	
	if( iterator_direct_prop->collect_obj )
	{
		if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetArrayObjectInRuntimeObjectsHeap(rt) ) )
		{
		}
		else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetListObjectInRuntimeObjectsHeap(rt) ) )
		{
			if( iterator_direct_prop->data.list_data.list_node )
			{
				DestroyObject( rt , iterator_direct_prop->data.list_data.list_node );
				iterator_direct_prop->data.list_data.list_node = NULL ;
			}
		}
		else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetMapObjectInRuntimeObjectsHeap(rt) ) )
		{
		}
		else
		{
		}
		
		DestroyObject( rt , iterator_direct_prop->collect_obj );
		iterator_direct_prop->collect_obj = NULL ;
	}
	
	memset( iterator_direct_prop , 0x00 , sizeof(struct ZlangDirectProperty_iterator) );
	
	iterator_direct_prop->collect_obj = AllocObject( rt ) ;
	if( iterator_direct_prop->collect_obj == NULL )
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
		return GetRuntimeErrorNo(rt);
	}
	
	nret = ReferObject( rt , iterator_direct_prop->collect_obj , collect_obj ) ;
	if( nret )
	{
		DestroyObject( rt , iterator_direct_prop->collect_obj );
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
		return GetRuntimeErrorNo(rt);
	}
	
	if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetArrayObjectInRuntimeObjectsHeap(rt) ) )
	{
		nret = CallRuntimeFunction_array_Length( rt , iterator_direct_prop->collect_obj , & length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
			return nret;
		}
		
		if( length >= 1 )
			iterator_direct_prop->data.array_data.element_no = 1 ;
		else
			iterator_direct_prop->data.array_data.element_no = -1 ;
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
		
		return 0;
	}
	else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetListObjectInRuntimeObjectsHeap(rt) ) )
	{
		iterator_direct_prop->data.list_data.list_node = CloneListNodeObject( rt , NULL ) ;
		if( iterator_direct_prop->data.list_data.list_node == NULL )
		{
			DestroyObject( rt , iterator_direct_prop->collect_obj );
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
			return GetRuntimeErrorNo(rt);
		}
		
		nret = CallRuntimeFunction_list_GetHead( rt , iterator_direct_prop->collect_obj , & (iterator_direct_prop->data.list_data.list_node) ) ;
		if( nret )
			return nret;
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
		
		return 0;
	}
	else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetMapObjectInRuntimeObjectsHeap(rt) ) )
	{
		nret = CallRuntimeFunction_map_TravelNextKey( rt , iterator_direct_prop->collect_obj , & (iterator_direct_prop->data.map_data.key) ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
			return nret;
		}
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
		
		return 0;
	}
	else
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
		
		return ZLANG_ERROR_INTERNAL;
	}
}

ZlangInvokeFunction ZlangInvokeFunction_iterator_TravelFirst_object;
int ZlangInvokeFunction_iterator_TravelFirst_object( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int			nret = 0 ;
	
	nret = iterator_TravelFirst( rt , obj , in1 ) ;
	if( nret )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	return 0;
}

ZlangDirectFunction_iterator_TravelLast iterator_TravelLast;
int iterator_TravelLast( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *collect_obj )
{
	struct ZlangDirectProperty_iterator	*iterator_direct_prop = GetObjectDirectProperty(obj) ;
	int32_t					length ;
	int					nret = 0 ;
	
	if( ! IsTypeOf( rt , collect_obj , GetArrayObjectInRuntimeObjectsHeap(rt) ) && ! IsTypeOf( rt , collect_obj , GetListObjectInRuntimeObjectsHeap(rt) ) && ! IsTypeOf( rt , collect_obj , GetMapObjectInRuntimeObjectsHeap(rt) ) )
		return ZLANG_ERROR_TYPE_OF_OBJECT_NOT_MATCHED;
	
	IF_ATOMIC_OBJECT_THEN_LOCK_ANOTHER_OBJECT( obj , collect_obj )
	
	if( iterator_direct_prop->collect_obj )
	{
		if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetArrayObjectInRuntimeObjectsHeap(rt) ) )
		{
		}
		else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetListObjectInRuntimeObjectsHeap(rt) ) )
		{
			if( iterator_direct_prop->data.list_data.list_node )
			{
				DestroyObject( rt , iterator_direct_prop->data.list_data.list_node );
				iterator_direct_prop->data.list_data.list_node = NULL ;
			}
		}
		else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetMapObjectInRuntimeObjectsHeap(rt) ) )
		{
		}
		else
		{
		}
		
		DestroyObject( rt , iterator_direct_prop->collect_obj );
		iterator_direct_prop->collect_obj = NULL ;
	}
	
	memset( iterator_direct_prop , 0x00 , sizeof(struct ZlangDirectProperty_iterator) );
	
	iterator_direct_prop->collect_obj = AllocObject( rt ) ;
	if( iterator_direct_prop->collect_obj == NULL )
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
		return GetRuntimeErrorNo(rt);
	}
	
	nret = ReferObject( rt , iterator_direct_prop->collect_obj , collect_obj ) ;
	if( nret )
	{
		DestroyObject( rt , iterator_direct_prop->collect_obj );
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
		return GetRuntimeErrorNo(rt);
	}
	
	if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetArrayObjectInRuntimeObjectsHeap(rt) ) )
	{
		nret = CallRuntimeFunction_array_Length( rt , iterator_direct_prop->collect_obj , & length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
			return nret;
		}
		
		if( length >= 1 )
			iterator_direct_prop->data.array_data.element_no = length ;
		else
			iterator_direct_prop->data.array_data.element_no = -1 ;
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
		
		return 0;
	}
	else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetListObjectInRuntimeObjectsHeap(rt) ) )
	{
		iterator_direct_prop->data.list_data.list_node = CloneListNodeObject( rt , NULL ) ;
		if( iterator_direct_prop->data.list_data.list_node == NULL )
		{
			DestroyObject( rt , iterator_direct_prop->collect_obj );
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
			return GetRuntimeErrorNo(rt);
		}
		
		nret = CallRuntimeFunction_list_GetTail( rt , iterator_direct_prop->collect_obj , & (iterator_direct_prop->data.list_data.list_node) ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
			return nret;
		}
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
		
		return 0;
	}
	else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetMapObjectInRuntimeObjectsHeap(rt) ) )
	{
		nret = CallRuntimeFunction_map_TravelPrevKey( rt , iterator_direct_prop->collect_obj , & (iterator_direct_prop->data.map_data.key) ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
			return nret;
		}
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
		
		return 0;
	}
	else
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , collect_obj );
		
		return ZLANG_ERROR_INTERNAL;
	}
}

ZlangInvokeFunction ZlangInvokeFunction_iterator_TravelLast_object;
int ZlangInvokeFunction_iterator_TravelLast_object( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int			nret = 0 ;
	
	nret = iterator_TravelLast( rt , obj , in1 ) ;
	if( nret )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	return 0;
}

ZlangDirectFunction_iterator_TravelNext iterator_TravelNext;
int iterator_TravelNext( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_iterator	*iterator_direct_prop = GetObjectDirectProperty(obj) ;
	int32_t					length ;
	int					nret = 0 ;
	
	if( iterator_direct_prop->collect_obj == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	IF_ATOMIC_OBJECT_THEN_LOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj )
	
	if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetArrayObjectInRuntimeObjectsHeap(rt) ) )
	{
		if( iterator_direct_prop->data.array_data.element_no == -1 )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return -1;
		}
		
		nret = CallRuntimeFunction_array_Length( rt , iterator_direct_prop->collect_obj , & length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		
		if( length >= 1 )
		{
			if( iterator_direct_prop->is_removed < 0 )
			{
				iterator_direct_prop->is_removed = 0 ;
				goto _GOTO_TRAVELNEXT_ARRAY;
			}
			else if( iterator_direct_prop->is_removed > 0 )
			{
				iterator_direct_prop->is_removed = 0 ;
			}
			else
			{
_GOTO_TRAVELNEXT_ARRAY:
				iterator_direct_prop->data.array_data.element_no++;
				if( iterator_direct_prop->data.array_data.element_no > length )
				{
					iterator_direct_prop->data.array_data.element_no = -1 ;
					IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
					return 1;
				}
			}
		}
		else
		{
			iterator_direct_prop->data.array_data.element_no = -1 ;
		}
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return 0;
	}
	else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetListObjectInRuntimeObjectsHeap(rt) ) )
	{
		if( iterator_direct_prop->data.list_data.list_node == NULL )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return -1;
		}
		
		nret = CallRuntimeFunction_list_Length( rt , iterator_direct_prop->collect_obj , & length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		
		if( length >= 1 )
		{
			if( iterator_direct_prop->is_removed < 0 )
			{
				iterator_direct_prop->is_removed = 0 ;
				goto _GOTO_TRAVELNEXT_LIST;
			}
			else if( iterator_direct_prop->is_removed > 0 )
			{
				iterator_direct_prop->is_removed = 0 ;
			}
			else
			{
_GOTO_TRAVELNEXT_LIST:
				nret = CallRuntimeFunction_list_node_TravelNext( rt , iterator_direct_prop->data.list_data.list_node ) ;
				if( nret )
				{
					IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
					return 1;
				}
			}
		}
		else
		{
			if( iterator_direct_prop->data.list_data.list_node )
			{
				DestroyObject( rt , iterator_direct_prop->data.list_data.list_node );
				iterator_direct_prop->data.list_data.list_node = NULL ;
			}
			
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			
			return 1;
		}
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return 0;
	}
	else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetMapObjectInRuntimeObjectsHeap(rt) ) )
	{
		nret = CallRuntimeFunction_map_Length( rt , iterator_direct_prop->collect_obj , & length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		
		if( length >= 1 )
		{
			if( iterator_direct_prop->is_removed )
			{
				iterator_direct_prop->data.map_data.key = iterator_direct_prop->data.map_data.next_key ;
				iterator_direct_prop->data.map_data.prev_key = NULL ;
				iterator_direct_prop->is_removed = 0 ;
			}
			else
			{
				nret = CallRuntimeFunction_map_TravelNextKey( rt , iterator_direct_prop->collect_obj , & (iterator_direct_prop->data.map_data.key) ) ;
				if( nret )
				{
					IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
					return 1;
				}
			}
		}
		else
		{
			iterator_direct_prop->data.map_data.key = NULL ;
		}
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return 0;
	}
	else
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return ZLANG_ERROR_INTERNAL;
	}
}

ZlangInvokeFunction ZlangInvokeFunction_iterator_TravelNext;
int ZlangInvokeFunction_iterator_TravelNext( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int			nret = 0 ;
	
	nret = iterator_TravelNext( rt , obj ) ;
	if( nret )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	return 0;
}

ZlangDirectFunction_iterator_TravelPrev iterator_TravelPrev;
int iterator_TravelPrev( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_iterator	*iterator_direct_prop = GetObjectDirectProperty(obj) ;
	int32_t					length ;
	int					nret = 0 ;
	
	if( iterator_direct_prop->collect_obj == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	IF_ATOMIC_OBJECT_THEN_LOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj )
	
	if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetArrayObjectInRuntimeObjectsHeap(rt) ) )
	{
		if( iterator_direct_prop->data.array_data.element_no == -1 )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return -1;
		}
		
		nret = CallRuntimeFunction_array_Length( rt , iterator_direct_prop->collect_obj , & length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		
		if( length >= 1 )
		{
			if( iterator_direct_prop->is_removed < 0 )
			{
				iterator_direct_prop->is_removed = 0 ;
			}
			else if( iterator_direct_prop->is_removed > 0 )
			{
				iterator_direct_prop->is_removed = 0 ;
				goto _GOTO_TRAVELPREV_ARRAY;
			}
			else
			{
_GOTO_TRAVELPREV_ARRAY:
				iterator_direct_prop->data.array_data.element_no--;
				if( iterator_direct_prop->data.array_data.element_no < 1 )
				{
					iterator_direct_prop->data.array_data.element_no = -1 ;
					IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
					return 1;
				}
			}
		}
		else
		{
			iterator_direct_prop->data.array_data.element_no = -1 ;
			iterator_direct_prop->is_removed = 0 ;
		}
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return 0;
	}
	else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetListObjectInRuntimeObjectsHeap(rt) ) )
	{
		if( iterator_direct_prop->data.list_data.list_node == NULL )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return -1;
		}
		
		nret = CallRuntimeFunction_list_Length( rt , iterator_direct_prop->collect_obj , & length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		
		if( length >= 1 )
		{
			if( iterator_direct_prop->is_removed < 0 )
			{
				iterator_direct_prop->is_removed = 0 ;
			}
			else if( iterator_direct_prop->is_removed > 0 )
			{
				iterator_direct_prop->is_removed = 0 ;
				goto _GOTO_TRAVELPREV_LIST;
			}
			else
			{
_GOTO_TRAVELPREV_LIST:
				nret = CallRuntimeFunction_list_node_TravelPrev( rt , iterator_direct_prop->data.list_data.list_node ) ;
				if( nret )
				{
					IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
					return 1;
				}
			}
		}
		else
		{
			if( iterator_direct_prop->data.list_data.list_node )
			{
				DestroyObject( rt , iterator_direct_prop->data.list_data.list_node );
				iterator_direct_prop->data.list_data.list_node = NULL ;
			}
			
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			
			return 1;
		}
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return 0;
	}
	else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetMapObjectInRuntimeObjectsHeap(rt) ) )
	{
		nret = CallRuntimeFunction_map_Length( rt , iterator_direct_prop->collect_obj , & length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		
		if( length >= 1 )
		{
			if( iterator_direct_prop->is_removed )
			{
				iterator_direct_prop->data.map_data.key = iterator_direct_prop->data.map_data.prev_key ;
				iterator_direct_prop->data.map_data.next_key = NULL ;
				iterator_direct_prop->is_removed = 0 ;
			}
			else
			{
				nret = CallRuntimeFunction_map_TravelPrevKey( rt , iterator_direct_prop->collect_obj , & (iterator_direct_prop->data.map_data.key) ) ;
				if( nret )
				{
					IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
					return 1;
				}
			}
		}
		else
		{
			iterator_direct_prop->data.map_data.key = NULL ;
		}
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return 0;
	}
	else
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return ZLANG_ERROR_INTERNAL;
	}
}

ZlangInvokeFunction ZlangInvokeFunction_iterator_TravelPrev;
int ZlangInvokeFunction_iterator_TravelPrev( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int			nret = 0 ;
	
	nret = iterator_TravelPrev( rt , obj ) ;
	if( nret )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	return 0;
}

ZlangDirectFunction_iterator_IsTravelOver iterator_IsTravelOver;
int iterator_IsTravelOver( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_iterator	*iterator_direct_prop = GetObjectDirectProperty(obj) ;
	int					nret = 0 ;
	
	if( iterator_direct_prop->collect_obj == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	IF_ATOMIC_OBJECT_THEN_LOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj )
	
	if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetArrayObjectInRuntimeObjectsHeap(rt) ) )
	{
		if( iterator_direct_prop->data.array_data.element_no == -1 )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return 1;
		}
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return 0;
	}
	else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetListObjectInRuntimeObjectsHeap(rt) ) )
	{
		if( iterator_direct_prop->data.list_data.list_node == NULL )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return 1;
		}
		
		nret = CallRuntimeFunction_list_node_IsTravelOver( rt , iterator_direct_prop->data.list_data.list_node ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return 1;
		}
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return 0;
	}
	else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetMapObjectInRuntimeObjectsHeap(rt) ) )
	{
		if( iterator_direct_prop->data.map_data.key == NULL )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return 1;
		}
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return 0;
	}
	else
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return ZLANG_ERROR_INTERNAL;
	}
}

ZlangInvokeFunction ZlangInvokeFunction_iterator_IsTravelOver;
int ZlangInvokeFunction_iterator_IsTravelOver( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int			nret = 0 ;
	
	nret = iterator_IsTravelOver( rt , obj ) ;
	if( nret == 1 )
	{ 
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
		return 0;
	}
	else if( nret )
	{
		return nret;
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
	return 0;
}

ZlangDirectFunction_iterator_GetElement iterator_GetElement;
int iterator_GetElement( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject **element_obj )
{
	struct ZlangDirectProperty_iterator	*iterator_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*elem = NULL ;
	int32_t					length ;
	int					nret = 0 ;
	
	if( iterator_direct_prop->collect_obj == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	IF_ATOMIC_OBJECT_THEN_LOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj )
	
	if( iterator_direct_prop->is_removed )
	{
		if( element_obj )
			(*element_obj) = NULL ;
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		return 0;
	}
	
	if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetArrayObjectInRuntimeObjectsHeap(rt) ) )
	{
		if( iterator_direct_prop->data.array_data.element_no == -1 )
		{
			if( element_obj )
				(*element_obj) = NULL ;
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return 0;
		}
		
		nret = CallRuntimeFunction_array_Length( rt , iterator_direct_prop->collect_obj , & length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		if( length == 0 )
		{
			if( element_obj )
				(*element_obj) = NULL ;
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return 0;
		}
		
		if( iterator_direct_prop->data.array_data.element_no < 1 || iterator_direct_prop->data.array_data.element_no > length )
		{
			if( element_obj )
				(*element_obj) = NULL ;
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return 0;
		}
		
		nret = CallRuntimeFunction_array_Get( rt , iterator_direct_prop->collect_obj , iterator_direct_prop->data.array_data.element_no , & elem ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		
		if( element_obj )
			(*element_obj) = elem ;
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		return 0;
	}
	else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetListObjectInRuntimeObjectsHeap(rt) ) )
	{
		if( iterator_direct_prop->data.list_data.list_node == NULL )
		{
			if( element_obj )
				(*element_obj) = NULL ;
		}
		
		nret = CallRuntimeFunction_list_Length( rt , iterator_direct_prop->collect_obj , & length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		if( length == 0 )
		{
			if( element_obj )
				(*element_obj) = NULL ;
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return 0;
		}
		
		nret = CallRuntimeFunction_list_node_GetMember( rt , iterator_direct_prop->data.list_data.list_node , & elem ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		
		if( element_obj )
			(*element_obj) = elem ;
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		return 0;
		
	}
	else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetMapObjectInRuntimeObjectsHeap(rt) ) )
	{
		if( iterator_direct_prop->data.map_data.key == NULL )
		{
			if( element_obj )
				(*element_obj) = NULL ;
		}
		
		nret = CallRuntimeFunction_map_Length( rt , iterator_direct_prop->collect_obj , & length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		if( length == 0 )
		{
			if( element_obj )
				(*element_obj) = NULL ;
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return 0;
		}
		
		if( element_obj )
			(*element_obj) = iterator_direct_prop->data.map_data.key ;
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		return 0;
	}
	else
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return ZLANG_ERROR_INTERNAL;
	}
}

ZlangInvokeFunction ZlangInvokeFunction_iterator_GetElement;
int ZlangInvokeFunction_iterator_GetElement( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject	*element_obj = NULL ;
	int			nret = 0 ;
	
	nret = iterator_GetElement( rt , obj , & element_obj ) ;
	if( nret )
	{
		UnreferObject( rt , out1 );
		return 0;
	}
	
	nret = ReferObject( rt , out1 , element_obj ) ;
	if( nret )
	{
		UnreferObject( rt , out1 );
		return 0;
	}
	
	return 0;
}

ZlangDirectFunction_iterator_Remove iterator_Remove;
int iterator_Remove( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_iterator	*iterator_direct_prop = GetObjectDirectProperty(obj) ;
	int32_t					length ;
	int					nret = 0 ;
	
	if( iterator_direct_prop->collect_obj == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	IF_ATOMIC_OBJECT_THEN_LOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj )
	
	if( iterator_direct_prop->is_removed )
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		return -1;
	}
	
	if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetArrayObjectInRuntimeObjectsHeap(rt) ) )
	{
		nret = CallRuntimeFunction_array_Length( rt , iterator_direct_prop->collect_obj , & length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		if( length == 0 )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return -1;
		}
		
		if( iterator_direct_prop->data.array_data.element_no <= 0 || iterator_direct_prop->data.array_data.element_no > length )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return -1;
		}
		
		CallRuntimeFunction_array_Remove( rt , iterator_direct_prop->collect_obj , iterator_direct_prop->data.array_data.element_no );
		if( iterator_direct_prop->data.array_data.element_no == length )
		{
			iterator_direct_prop->data.array_data.element_no--;
			iterator_direct_prop->is_removed = -1 ;
		}
		else
		{
			iterator_direct_prop->is_removed = 1 ;
		}
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return 0;
	}
	else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetListObjectInRuntimeObjectsHeap(rt) ) )
	{
		nret = CallRuntimeFunction_list_Length( rt , iterator_direct_prop->collect_obj , & length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		if( length == 0 )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return -1;
		}
		
		iterator_direct_prop->is_removed = CallRuntimeFunction_list_node_Remove( rt , iterator_direct_prop->data.list_data.list_node ) ;
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return 0;
	}
	else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetMapObjectInRuntimeObjectsHeap(rt) ) )
	{
		nret = CallRuntimeFunction_map_Length( rt , iterator_direct_prop->collect_obj , & length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		if( length == 0 )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return -1;
		}
		
		iterator_direct_prop->data.map_data.prev_key = iterator_direct_prop->data.map_data.next_key = iterator_direct_prop->data.map_data.key ;
		CallRuntimeFunction_map_TravelPrevKey( rt , iterator_direct_prop->collect_obj , & (iterator_direct_prop->data.map_data.prev_key) );
		CallRuntimeFunction_map_TravelNextKey( rt , iterator_direct_prop->collect_obj , & (iterator_direct_prop->data.map_data.next_key) );
		iterator_direct_prop->is_removed = CallRuntimeFunction_map_Remove( rt , iterator_direct_prop->collect_obj , & (iterator_direct_prop->data.map_data.key) ) ;
		iterator_direct_prop->data.map_data.key = NULL ;
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return 0;
	}
	else
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return ZLANG_ERROR_INTERNAL;
	}
}

ZlangInvokeFunction ZlangInvokeFunction_iterator_Remove;
int ZlangInvokeFunction_iterator_Remove( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int			nret = 0 ;
	
	nret = iterator_Remove( rt , obj ) ;
	if( nret )
	{ 
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	return 0;
}

ZlangDirectFunction_iterator_Length iterator_Length;
int iterator_Length( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t *length )
{
	struct ZlangDirectProperty_iterator	*iterator_direct_prop = GetObjectDirectProperty(obj) ;
	int					nret = 0 ;
	
	if( iterator_direct_prop->collect_obj == NULL )
		return ZLANG_ERROR_PARAMETER;
	
	IF_ATOMIC_OBJECT_THEN_LOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj )
	
	if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetArrayObjectInRuntimeObjectsHeap(rt) ) )
	{
		nret = CallRuntimeFunction_array_Length( rt , iterator_direct_prop->collect_obj , length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return 0;
	}
	else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetListObjectInRuntimeObjectsHeap(rt) ) )
	{
		nret = CallRuntimeFunction_list_Length( rt , iterator_direct_prop->collect_obj , length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return 0;
	}
	else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetMapObjectInRuntimeObjectsHeap(rt) ) )
	{
		nret = CallRuntimeFunction_map_Length( rt , iterator_direct_prop->collect_obj , length ) ;
		if( nret )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
			return nret;
		}
		
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return 0;
	}
	else
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK_ANOTHER_OBJECT( obj , iterator_direct_prop->collect_obj );
		
		return ZLANG_ERROR_INTERNAL;
	}
}

ZlangInvokeFunction ZlangInvokeFunction_iterator_Length;
int ZlangInvokeFunction_iterator_Length( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int32_t			length ;
	int			nret = 0 ;
	
	nret = iterator_Length( rt , obj , & length ) ;
	if( nret < 0 )
	{ 
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -1 );
		return 0;
	}
	
	CallRuntimeFunction_int_SetIntValue( rt , out1 , length );
	return 0;
}

ZlangCreateDirectPropertyFunction ZlangCreateDirectProperty_iterator;
void *ZlangCreateDirectProperty_iterator( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_iterator	*iterator_direct_prop = NULL ;
	
	iterator_direct_prop = (struct ZlangDirectProperty_iterator *)ZLMALLOC( sizeof(struct ZlangDirectProperty_iterator) ) ;
	if( iterator_direct_prop == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for entity" )
		return NULL;
	}
	memset( iterator_direct_prop , 0x00 , sizeof(struct ZlangDirectProperty_iterator) );
	
	return (struct ZlangEntity *)iterator_direct_prop;
}

ZlangDestroyDirectPropertyFunction ZlangDestroyDirectProperty_iterator;
void ZlangDestroyDirectProperty_iterator( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_iterator	*iterator_direct_prop = GetObjectDirectProperty(obj) ;
	
	if( iterator_direct_prop->collect_obj )
	{
		if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetArrayObjectInRuntimeObjectsHeap(rt) ) )
		{
		}
		else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetListObjectInRuntimeObjectsHeap(rt) ) )
		{
			if( iterator_direct_prop->data.list_data.list_node )
			{
				DestroyObject( rt , iterator_direct_prop->data.list_data.list_node );
				iterator_direct_prop->data.list_data.list_node = NULL ;
			}
		}
		else if( IsTypeOf( rt , iterator_direct_prop->collect_obj , GetMapObjectInRuntimeObjectsHeap(rt) ) )
		{
		}
		else
		{
		}
		
		DestroyObject( rt , iterator_direct_prop->collect_obj );
		iterator_direct_prop->collect_obj = NULL ;
	}
	
	ZLFREE( iterator_direct_prop );
	
	return;
}

ZlangSummarizeDirectPropertySizeFunction ZlangSummarizeDirectPropertySize_iterator;
void ZlangSummarizeDirectPropertySize_iterator( struct ZlangRuntime *rt , struct ZlangObject *obj , size_t *summarized_obj_size , size_t *summarized_direct_prop_size )
{
	SUMMARIZE_SIZE( summarized_direct_prop_size , sizeof(struct ZlangDirectProperty_iterator) )
	return;
}

static struct ZlangDirectFunctions direct_funcs_iterator =
	{
		ZLANG_OBJECT_iterator ,
		
		ZlangCreateDirectProperty_iterator ,
		ZlangDestroyDirectProperty_iterator ,
		
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		NULL ,
		NULL ,
		
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		ZlangSummarizeDirectPropertySize_iterator ,
	} ;

ZlangImportObjectFunction ZlangImportObject_iterator;
struct ZlangObject *ZlangImportObject_iterator( struct ZlangRuntime *rt )
{
	struct ZlangObject	*obj = NULL ;
	struct ZlangFunction	*func = NULL ;
	int			nret = 0 ;
	
	nret = ImportObject( rt , & obj , ZLANG_OBJECT_iterator , & direct_funcs_iterator , sizeof(struct ZlangDirectFunctions) , NULL ) ;
	if( nret )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_LINK_FUNC_TO_ENTITY , "import object to global objects heap" )
		DestroyObject( rt , obj );
		return NULL;
	}
	
	/* iterator.TravelFirst(object) */
	func = AddFunctionAndParametersInObject( rt , obj , "TravelFirst" , "TravelFirst(object)" , ZlangInvokeFunction_iterator_TravelFirst_object , ZLANG_OBJECT_bool , ZLANG_OBJECT_object,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* iterator.TravelLast(object) */
	func = AddFunctionAndParametersInObject( rt , obj , "TravelLast" , "TravelLast(object)" , ZlangInvokeFunction_iterator_TravelLast_object , ZLANG_OBJECT_bool , ZLANG_OBJECT_object,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* iterator.TravelNext() */
	func = AddFunctionAndParametersInObject( rt , obj , "TravelNext" , "TravelNext()" , ZlangInvokeFunction_iterator_TravelNext , ZLANG_OBJECT_bool , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* iterator.TravelPrev() */
	func = AddFunctionAndParametersInObject( rt , obj , "TravelPrev" , "TravelPrev()" , ZlangInvokeFunction_iterator_TravelPrev , ZLANG_OBJECT_bool , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* iterator.IsTravelOver() */
	func = AddFunctionAndParametersInObject( rt , obj , "IsTravelOver" , "IsTravelOver()" , ZlangInvokeFunction_iterator_IsTravelOver , ZLANG_OBJECT_bool , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* iterator.GetElement() */
	func = AddFunctionAndParametersInObject( rt , obj , "GetElement" , "GetElement()" , ZlangInvokeFunction_iterator_GetElement , ZLANG_OBJECT_object , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* iterator.Remove() */
	func = AddFunctionAndParametersInObject( rt , obj , "Remove" , "Remove()" , ZlangInvokeFunction_iterator_Remove , ZLANG_OBJECT_bool , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* iterator.Length() */
	func = AddFunctionAndParametersInObject( rt , obj , "Length" , "Length()" , ZlangInvokeFunction_iterator_Length , ZLANG_OBJECT_int , NULL ) ;
	if( func == NULL )
		return NULL;
	
	SetRuntimeFunction_iterator_TravelFirst( rt , iterator_TravelFirst );
	SetRuntimeFunction_iterator_TravelLast( rt , iterator_TravelLast );
	SetRuntimeFunction_iterator_TravelNext( rt , iterator_TravelNext );
	SetRuntimeFunction_iterator_TravelPrev( rt , iterator_TravelPrev );
	SetRuntimeFunction_iterator_IsTravelOver( rt , iterator_IsTravelOver );
	SetRuntimeFunction_iterator_GetElement( rt , iterator_GetElement );
	SetRuntimeFunction_iterator_Remove( rt , iterator_Remove );
	SetRuntimeFunction_iterator_Length( rt , iterator_Length );
	
	return obj ;
}

